home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktimeintro / movie from dataref / common files / macframework.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  53.6 KB  |  2,027 lines

  1. //////////
  2. //
  3. //    File:        MacFramework.c
  4. //
  5. //    Contains:    Basic support for playing QuickTime and QuickTime VR movies in a Macintosh application.
  6. //                MacFramework is a simple QuickTime viewer and editor framework. It handles windows,
  7. //                menus, events, and other low-level things. Put your application-specific code into the
  8. //                file ComApplication.c. 
  9. //
  10. //    Written by:    Tim Monroe
  11. //                Based on the MovieShell code written by Apple DTS (Kent Sandvik).
  12. //
  13. //    Copyright:    © 1994-1999 by Apple Computer, Inc., all rights reserved.
  14. //
  15. //    Change History (most recent first):GetFrontWindow
  16. //
  17. //       <52>         06/07/99    rtm        added GetFrontAppWindow and GetNextAppWindow; revised existing GetFrontMovieWindow
  18. //                                    and GetNextMovieWindow
  19. //       <51>         06/05/99    rtm        added gAppFSSpec to keep track of the application's location
  20. //       <50>         05/12/99    rtm        tweaked DoSaveAsMovieWindow to ensure it creates single-fork movies; renamed it
  21. //                                    as DoSaveAsMovieFile
  22. //       <49>         05/11/99    rtm        further work on DoSaveAsMovieWindow
  23. //       <48>         05/10/99    rtm        commented CloseMovieFile out of DoCreateMovieWindow; tweaked DoUpdateMovieFile
  24. //                                    and DoSaveAsMovieWindow to reflect changes
  25. //       <47>         05/06/99    rtm        added createMovieFileDontCreateResFile flag to FlattenMovieData call
  26. //                                    in DoSaveAsMovieWindow
  27. //       <46>         03/31/99    rtm        added default name for new movies; added DoSaveAsMovieWindow to implement
  28. //                                    correct "Save As" behavior
  29. //       <45>         03/18/99    rtm        added SetMoviePlayHints call in DoCreateMovieWindow to support possible
  30. //                                    dynamic resizing of streamed movies
  31. //       <44>         01/26/99    rtm        added EnableItem call for iSaveAs menu item in AdjustMenus
  32. //       <43>         12/09/98    rtm        modified inDrag case in MainEventLoop to handle non-movie windows too
  33. //       <42>         10/27/98    rtm        reworked DoCreateMovieWindow to take movie name from the FSSpec when
  34. //                                    a movie is passed in
  35. //       <41>         10/20/98    rtm        added default progress procedure for all movies (in DoCreateMovieWindow)
  36. //       <40>         10/15/98    rtm        added autostarting for streamed movies
  37. //       <39>         05/06/98    rtm        added CheckQuickTimeRegistration call to main
  38. //       <38>         04/16/98    rtm        added EventAvail loop to InitMacEnvironment
  39. //       <37>         02/13/98    rtm        added GetWindowWidth; reworked SizeWindowToMovie to call it
  40. //       <36>         02/09/98    rtm        added GetWindowReferenceFromPort
  41. //       <35>         02/02/98    rtm        added SetMenuState
  42. //       <34>         01/06/98    rtm        added DoActivateWindow call to ShowAboutBox
  43. //       <33>         12/22/97    rtm        added AdjustMenus call to HandleKeyPress, as prescribed by Inside Macintosh:
  44. //                                    Macintosh Toolbox Essentials, p. 3-78
  45. //       <32>         12/18/97    rtm        moved InitApplication call from InitMacEnvironment to main (to follow EnterMovies)
  46. //       <31>         12/15/97    rtm        added mouseDown case to StandardModalDialogEventFilter
  47. //       <30>         12/12/97    rtm        reworked DoCreateMovieWindow
  48. //       <29>         12/08/97    rtm        finished support for Save in DoDestroyMovieWindow; moved main to this file
  49. //       <28>         12/05/97    rtm        added fDirty flag to window object; begun supporting Save and Save As
  50. //       <27>         12/01/97    rtm        added gAppResFile global variable; see ShowAboutBox for details
  51. //       <26>         11/07/97    rtm        revised call to DoApplicationEventLoopAction
  52. //       <25>         10/31/97    rtm        fixed crashing bug in DoDestroyMovieWindow; see note there
  53. //       <24>         10/30/97    rtm        added GetPortFromWindowReference
  54. //       <23>         09/18/97    rtm        added GetFrontWindow and GetNextWindow
  55. //       <22>         09/11/97    rtm        added SizeWindowToMovie
  56. //       <21>         07/23/97    rtm        added GetWindowObjectFromWindow; rewrote GetWindowObjectFromFrontWindow
  57. //                                    and all other functions that previously called GetWRefCon directly
  58. //       <20>         07/18/97    rtm        added calls to new Dialog Manager standard filter proc if it's available
  59. //       <19>         07/17/97    rtm        used new Dialog Manager constants for ok and cancel;
  60. //                                    added QuitFramework (called from iQuit menu and from 'quit' Apple event)
  61. //       <18>         07/15/97    rtm        revised GetMCFromFrontWindow to use GetWindowObjectFromFrontWindow;
  62. //                                    added AdjustMenus to InitMenuBar
  63. //       <17>         07/11/97    rtm        changed event loop to call AdjustMenus only before MenuSelect;
  64. //                                    added DoApplicationEventLoopAction
  65. //       <16>         06/12/97    rtm        added standard modal dialog event filter and standard user item procedure
  66. //       <15>         06/10/97    rtm        replaced existing grow zone procedure with a better one
  67. //       <14>         06/05/97    rtm        added fCanResizeWindow to app data record, replacing an app global
  68. //       <13>         02/26/97    rtm        reworked AdjustMenus slightly; see <10> also
  69. //       <12>         02/17/97    rtm        reworked DoDestroyMovieWindow
  70. //       <11>         02/04/97    rtm        tweaked gLimitRect to fix bug #1624600
  71. //       <10>         02/03/97    rtm        Select All edit menu item now disabled for QTVR movies
  72. //       <9>         01/06/97    rtm        DoIdle now called for all open app windows
  73. //       <8>         01/02/97    rtm        added gAppInForeground flag
  74. //       <7>         12/17/96    rtm        fixed crashing bug in DoCreateMovieWindow
  75. //                                    (hitting Cancel in open dialog left wrong port setting)
  76. //       <6>         12/17/96    rtm        added GetAppDataFromFrontWindow, GetAppDataFromWindow, GetAppDataFromWindowObject
  77. //       <5>         12/09/96    rtm        added RemoveApplicationWindowObject hook to allow app-specific clean-up
  78. //       <4>         12/04/96    rtm        added support for high-level events
  79. //       <3>         12/02/96    rtm        added CheckMovieControllers function
  80. //       <2>         11/27/96    rtm        conversion to personal coding style
  81. //       <1>         12/20/94    khs        first file
  82. //       
  83. //////////
  84.  
  85. // application header files
  86. #include "MacFramework.h"
  87. #include "AppConfiguration.h"
  88. #include "CreateMovie.h"
  89.  
  90. // global variables
  91. Rect                gDefaultWindowRect;
  92. Rect                gLimitRect = {10, 10, 480, 640};    // max size for any window
  93. long                gMCFlags = kMCFlags;
  94.  
  95. Boolean             gQuitFlag = false;                    // flag that keeps track of termination state
  96. Boolean                gAppInForeground;                    // is our application in the foreground?    
  97. Boolean                gHasNewDialogCalls;                    // are the new Dialog Manager functions available?
  98.  
  99. unsigned long        gWNEsleep = kWNEDefaultSleep;        // WaitNextEvent sleep time
  100. Str255                 gWindowTitle = kDefaultWindowTitle;    // default name for created windows
  101. GrowZoneUPP            gAppGrowZoneUPP;                    // UPP to our grow zone callback
  102. ModalFilterUPP        gModalFilterUPP;                    // UPP to our custom dialog event filter
  103. UserItemUPP            gUserItemProcUPP;                    // UPP to our custom dialog user item procedure
  104. Handle                gEmergencyMemory;                    // handle to our emergency memory reserve
  105.  
  106. short                 gAppResFile = kInvalidFileRefNum;    // file reference number for this application's resource file
  107. FSSpec                gAppFSSpec;                            // file specification for the application itself
  108. Str255                gAppName;                            // the name of this application
  109.  
  110.  
  111. //////////
  112. //
  113. // main
  114. // Set up the application's execution environment; make sure QuickTime (etc.) is installed.
  115. //
  116. //////////
  117.  
  118. void main (void)
  119. {
  120.     OSErr        myErr = noErr;
  121.     
  122.     InitMacEnvironment(10L);            // 10 * MoreMasters
  123.     
  124.     if (!QTUtils_IsQuickTimeInstalled()) {
  125.         ShowWarning("\pThe QuickTime extension is not present in this system (exit)", 0);
  126.         ExitToShell();
  127.     }
  128.  
  129. #if TARGET_CPU_PPC    
  130.     if (!QTUtils_IsQuickTimeCFMInstalled()) {
  131.         ShowWarning("\pThe QuickTime PowerPlug extension is not available (exit)", 0);
  132.         ExitToShell();
  133.     }
  134. #endif 
  135.  
  136.     myErr = EnterMovies();
  137.     if (myErr != noErr) {
  138.         ShowWarning("\pCould not initialize the QuickTime environment (exit): ", myErr);
  139.         ExitToShell();
  140.     }
  141.  
  142.     // do any application-specific initialization
  143.     InitApplication(kInitAppPhase_BothPhases);
  144.  
  145.     MainEventLoop();                    // get and process commands until user quits
  146.     
  147.     ExitMovies();
  148.  
  149.     ExitToShell();
  150. }
  151.  
  152.  
  153. //////////
  154. //
  155. // InitMacEnvironment
  156. // Initialize the Macintosh runtime environment.
  157. //
  158. //////////
  159.  
  160. void InitMacEnvironment (long theNumMasters)
  161. {
  162.     long            myIndex;
  163.     EventRecord     myEvent;
  164.     short            myVRefNum;
  165.     long            myDirID;
  166.     OSErr            myErr;
  167.  
  168.     // add more space to the stack
  169.     InitStack(kExtraStackSpaceSize);
  170.             
  171.     // expand heap zone to its limit
  172.     MaxApplZone();
  173.     
  174.     // allocate master pointer blocks
  175.     for (myIndex = 0; myIndex < theNumMasters; myIndex++)
  176.         MoreMasters();
  177.     
  178.     InitGraf(&qd.thePort);
  179.     InitFonts();
  180.     InitWindows();
  181.     InitMenus();
  182.     TEInit();
  183.     InitDialogs(NULL);
  184.     InitCursor();
  185.  
  186.     // pull the application into the foreground; until an application has made a few calls
  187.     // to the Event Manager, MultiFinder keeps it in the background, and splash screens and
  188.     // alert boxes will remain in a background layer (this is documented in Tech Note #180)
  189.     for (myIndex = 1; myIndex <= kBroughtToFront; myIndex++)
  190.         myErr = EventAvail(everyEvent, &myEvent);
  191.     
  192.     // initialize and install the menu bar
  193.     InitMenubar();
  194.  
  195.     // install a grow zone procedure to handle low memory situations
  196.     gEmergencyMemory = NewHandle(kEmergencyMemorySize);
  197.     if (gEmergencyMemory != NULL) {
  198.         gAppGrowZoneUPP = NewGrowZoneProc(AppGrowZoneCallback);
  199.         SetGrowZone(gAppGrowZoneUPP);
  200.     }
  201.     
  202.     // initialize foreground/background state
  203.     gAppInForeground = true;
  204.     
  205.     // see whether the new Dialog Manager functions are available
  206.     gHasNewDialogCalls = QTUtils_TrapAvailable(_DialogDispatch);
  207.         
  208.     // create modal dialog filter and user item UPPs
  209.     gModalFilterUPP = NewModalFilterProc(StandardModalDialogEventFilter);
  210.     gUserItemProcUPP = NewUserItemProc(StandardUserItemProcedure);
  211.  
  212.     // get the application's resource file
  213.     gAppResFile = CurResFile();
  214.     
  215.     // get the application's name from the resource file
  216.     GetIndString(gAppName, kAppNameResID, kAppNameResIndex);
  217.     
  218.     // get the application's location and save it in gAppFSSpec
  219.     HGetVol(NULL, &myVRefNum, &myDirID);
  220.     FSMakeFSSpec(myVRefNum, myDirID, gAppName, &gAppFSSpec);
  221. }
  222.  
  223.  
  224. //////////
  225. //
  226. // InitStack
  227. // Add some extra space to the stack.
  228. //
  229. //////////
  230.  
  231. void InitStack (long theExtraStackSpace)
  232. {
  233.     Ptr            mySize;
  234.     
  235.     mySize = GetApplLimit();
  236.     SetApplLimit((Ptr)(mySize - theExtraStackSpace));
  237. }
  238.  
  239.  
  240. //////////
  241. //
  242. // AppGrowZoneCallback
  243. // A grow zone procedure. This is straight out of IM: Memory (pp. 1-46ff)
  244. //
  245. //////////
  246.  
  247. PASCAL_RTN long AppGrowZoneCallback (Size theBytesNeeded)
  248. {
  249. #pragma unused(theBytesNeeded)
  250.  
  251.     long        myA5;
  252.     Size        myBytesFreed;
  253.     
  254.     // get current A5; we might get called at a time that A5 isn't valid
  255.     myA5 = SetCurrentA5();
  256.     
  257.     if ((*gEmergencyMemory != NULL) && (gEmergencyMemory != GZSaveHnd())) {
  258.         EmptyHandle(gEmergencyMemory);
  259.         myBytesFreed = kEmergencyMemorySize;
  260.     } else {
  261.         myBytesFreed = 0;                        // no more memory to release    
  262.     }    
  263.         
  264.     myA5 = SetA5(myA5);
  265.     
  266.     return(myBytesFreed);
  267. }
  268.  
  269.  
  270. //////////
  271. //
  272. // InitMenubar
  273. // Set up the menu bar. This is straight out of IM: Macintosh Toolbox Essentials (pp. 3-50ff)
  274. //
  275. //////////
  276.  
  277. Boolean InitMenubar (void)
  278. {
  279.     Handle        myMenuHandle = NULL;
  280.     
  281.     myMenuHandle = GetNewMBar(mMenubar);                    // read the resource-defined menu bar
  282.     if (myMenuHandle == NULL)
  283.         return(false);
  284.     
  285.     SetMenuBar(myMenuHandle);                                // install the menus
  286.     DisposeHandle(myMenuHandle);
  287.     AppendResMenu(GetMenuHandle(mApple), 'DRVR');            // add desk accessory names to Apple menu
  288.     AdjustMenus();
  289.     DrawMenuBar();
  290.     
  291.     return(true);
  292. }
  293.  
  294.  
  295. //////////
  296. //
  297. // MainEventLoop
  298. // Retrieve and process events.
  299. //
  300. //////////
  301.  
  302. void MainEventLoop (void)
  303. {
  304.     EventRecord                myEvent;
  305.     WindowRef                myWindow;
  306.     Boolean                    isEventHandled;
  307.     short                    myWindowPart;
  308.     Rect                    myScreenRect;
  309.     Rect                    myRefreshArea;
  310.     
  311.     while (!gQuitFlag) {
  312.     
  313.         // make sure we've still got our memory reserve; reallocate it if it's been used
  314.         if ((gEmergencyMemory == NULL) || (*gEmergencyMemory == NULL))
  315.             ReallocateHandle(gEmergencyMemory, kEmergencyMemorySize);
  316.     
  317.         WaitNextEvent(everyEvent, &myEvent, gWNEsleep, NULL);
  318.         
  319.         // first, perform any application-specific event loop actions
  320.         isEventHandled = DoApplicationEventLoopAction(&myEvent);
  321.             
  322.         // then, let all active movie controllers have access to the event
  323.         if (!isEventHandled)
  324.             isEventHandled = CheckMovieControllers(&myEvent);
  325.  
  326.         // then, if this event hasn't been handled, pass it on to the case statement 
  327.         // that dispatches the event to the right function
  328.         if (!isEventHandled) {
  329.         
  330.             myWindow = FrontWindow();
  331.     
  332.             switch (myEvent.what) {
  333.                 case mouseDown:
  334.                 
  335.                     myWindowPart = FindWindow(myEvent.where, &myWindow);
  336.  
  337.                     // menu bar and window-related events:            
  338.                     switch (myWindowPart) {
  339.                         case inSysWindow:
  340.                             // a mouse click in a window belonging to a desk accessory
  341.                             SystemClick(&myEvent, myWindow);
  342.                             break;
  343.                             
  344.                         case inMenuBar:
  345.                             // a mouse click in the menu bar
  346.                             AdjustMenus();
  347.                             HandleMenuCommand(MenuSelect(myEvent.where));
  348.                             break;
  349.                             
  350.                         case inDrag: {
  351.                             WindowObject         myWindowObject = NULL;
  352.                             MovieController     myMC = NULL;
  353.                             Movie                myMovie = NULL;
  354.                             Rect                 myRect;
  355.                             
  356.                             myWindowObject = GetWindowObjectFromWindow(myWindow);
  357.                             if (myWindowObject != NULL) {
  358.                                 myMC = (**myWindowObject).fController;
  359.                                 if (myMC != NULL) {
  360.                                     myMovie = (**myWindowObject).fMovie;
  361.                                     if (myMovie != NULL) {
  362.                                         GetMovieBox(myMovie, &myRect);
  363.                                         myScreenRect = (**GetGrayRgn()).rgnBBox;
  364.                                         DragAlignedWindow(myWindow, myEvent.where, &myScreenRect, &myRect, NULL);
  365.                                     }
  366.                                 }
  367.                             } else {
  368.                                 myScreenRect = (**GetGrayRgn()).rgnBBox;
  369.                                 DragWindow(myWindow, myEvent.where, &myScreenRect);
  370.                             }
  371.                             
  372.                             break;                            
  373.                         }
  374.                             
  375.                         case inContent:
  376.                             if (myWindow != FrontWindow()) {
  377.                                 SelectWindow(myWindow);
  378.                                 MacSetPort(myWindow);
  379.                             } else {
  380.                                 HandleContentClick(myWindow, &myEvent);
  381.                             }
  382.                             
  383.                             break;
  384.                         
  385.                         case inGoAway:
  386.                             // if the window is closed, dispose the movie, the controller, and the window
  387.                             if (TrackGoAway(myWindow, myEvent.where))
  388.                                 DoDestroyMovieWindow(myWindow);
  389.                             break;
  390.                     } // end switch(myWindowPart)
  391.                     break;
  392.  
  393.                 // system-level events:
  394.                 case updateEvt:
  395.                     myWindow = (WindowReference)myEvent.message;
  396.                     if (myWindow != NULL) {
  397.                         myRefreshArea = ((**(myWindow->visRgn)).rgnBBox);
  398.                         DoUpdateWindow(myWindow, &myRefreshArea);
  399.                     }
  400.                     break;
  401.                     
  402.                 case keyDown:
  403.                 case autoKey:
  404.                     HandleKeyPress(&myEvent);
  405.                     break;
  406.                 
  407.                 case diskEvt: {
  408.                     Point            myPoint = {100, 100};
  409.                 
  410.                     if (HiWord(myEvent.message) != noErr)
  411.                         (void)DIBadMount(myPoint, myEvent.message);
  412.                     break;
  413.                 }
  414.                 
  415.                 case activateEvt:
  416.                     myWindow = (WindowReference)myEvent.message;
  417.                     
  418.                      if (IsAppWindow(myWindow)) {
  419.                         DoActivateWindow(myWindow, ((myEvent.modifiers & activeFlag) != 0 ));
  420.                     }
  421.                     break;
  422.                     
  423.                 case osEvt:
  424.                     switch ((myEvent.message >> 24) & 0x00FF) {        // get high byte of message
  425.                         case suspendResumeMessage:
  426.                         
  427.                             // set the foreground/background state
  428.                             if ((myEvent.message & resumeFlag) != 0)
  429.                                 gAppInForeground = true;
  430.                             else
  431.                                 gAppInForeground = false;
  432.                             
  433.                             // activate the front window, if there is one    
  434.                             myWindow = FrontWindow();
  435.                             if (myWindow != NULL)
  436.                                 DoActivateWindow(myWindow, !((myEvent.message & resumeFlag) == 0));
  437.                             break;
  438.                         
  439.                         case mouseMovedMessage:
  440.                             break;
  441.                     }
  442.                     break;
  443.                 
  444.                 case kHighLevelEvent:
  445.                     AEProcessAppleEvent(&myEvent);
  446.                     break;
  447.                     
  448.                 case nullEvent:
  449.                     // do idle-time processing for all open windows in our window list
  450.                     myWindow = GetFrontMovieWindow();
  451.                     while (myWindow != NULL) {
  452.                         if (gAppInForeground)
  453.                             DoIdle(myWindow);
  454.                             
  455.                         myWindow = GetNextMovieWindow(myWindow);
  456.                     }
  457.                     break;
  458.                     
  459.             } // switch (myEvent.what)
  460.         } // if (!isMovieEvent)
  461.     } // while (!gQuitFlag)
  462. }
  463.  
  464.  
  465. //////////
  466. //
  467. // HandleMenuCommand
  468. // Handle a menu selection.
  469. //
  470. //////////
  471.  
  472. void HandleMenuCommand (long theMenuResult)
  473. {
  474.     short        myMenuID, myMenuItem;
  475.     Str255        myDAName;
  476.     
  477.     MacSetCursor(&qd.arrow);
  478.  
  479.     myMenuID = HiWord(theMenuResult);
  480.     myMenuItem = LoWord(theMenuResult);
  481.     
  482.     switch (myMenuID) {
  483.     
  484.         case mApple:
  485.             switch (myMenuItem) {
  486.                 case iAbout:    // about box
  487.                     ShowAboutBox();     
  488.                     break;
  489.                 
  490.                 default:         // Apple menu handling
  491.                     GetMenuItemText(GetMenuHandle(mApple), myMenuItem, myDAName);
  492.                     (void)OpenDeskAcc(myDAName);
  493.                     break;
  494.             }
  495.             break;
  496.  
  497.         case mFile:
  498.             switch (myMenuItem) {
  499.                 case iNew:
  500.                     CreateAMovie();
  501.                     break;
  502.                     
  503.                 case iOpen:
  504.                     DoCreateMovieWindow(NULL, NULL);
  505.                     break;
  506.                 
  507.                 case iClose:
  508.                     DoDestroyMovieWindow(GetFrontAppWindow());
  509.                     break;
  510.                 
  511.                 case iSave:
  512.                     DoUpdateMovieFile(GetFrontMovieWindow());
  513.                     break;
  514.                     
  515.                 case iSaveAs:
  516.                     DoSaveAsMovieFile(GetFrontMovieWindow());
  517.                     break;
  518.                                     
  519.                 case iPrint: {
  520.                     MovieController        myMC;
  521.                     OSErr                myErr = noErr;
  522.  
  523.                     myMC = GetMCFromFrontWindow();
  524.                     if (myMC != NULL) {
  525.                         myErr = QTUtils_PrintMoviePICT(MCGetMovie(myMC), kDefaultX, kDefaultY, kPrintFrame); 
  526.                         if (myErr != noErr) {
  527.                             ShowWarning("\pCould not print!", myErr);
  528.                             SysBeep(kDefaultSysBeep);
  529.                         }
  530.                     } else
  531.                         SysBeep(kDefaultSysBeep);
  532.                     break;
  533.                 }
  534.  
  535.                 case iQuit:
  536.                     QuitFramework();
  537.                     break;
  538.                     
  539.             }
  540.             break;
  541.     
  542.         // provide the default controller cut, copy and paste functionality    
  543.         case mEdit: {
  544.             Movie                myMovie = NULL;
  545.             MovieController        myMC = NULL;
  546.             WindowObject        myWindowObject = NULL;
  547.             
  548.             myMC = GetMCFromFrontWindow();
  549.             myWindowObject = GetWindowObjectFromFrontWindow();
  550.             
  551.             if (myMenuItem == iPreferences) {
  552.                 HandleApplicationMenu(MENU_IDENTIFIER(myMenuID, myMenuItem));
  553.                 break;
  554.             }
  555.  
  556.             if ((myMC == NULL) || (myWindowObject == NULL))
  557.                 break;
  558.             
  559.             switch (myMenuItem) {
  560.                 case iUndo:
  561.                     MCUndo(myMC);
  562.                     (**myWindowObject).fDirty = true;
  563.                     break;
  564.                 
  565.                 case iCut:
  566.                     myMovie = MCCut(myMC);
  567.                     (**myWindowObject).fDirty = true;
  568.                     break;
  569.                 
  570.                 case iCopy:
  571.                     myMovie = MCCopy(myMC);
  572.                     break;
  573.                 
  574.                 case iPaste:
  575.                     MCPaste(myMC, NULL);
  576.                     (**myWindowObject).fDirty = true;
  577.                     break;
  578.                 
  579.                 case iClear:
  580.                     MCClear(myMC);
  581.                     (**myWindowObject).fDirty = true;
  582.                     break;
  583.                 
  584.                 case iSelectAll:
  585.                     if (QTUtils_SelectAllMovie(myMC) != noErr)
  586.                         SysBeep(kDefaultSysBeep);
  587.                     break;
  588.             }
  589.             
  590.             if (myMovie) {
  591.                 PutMovieOnScrap(myMovie, 0L);
  592.                 DisposeMovie(myMovie);
  593.             }
  594.             
  595.             break;
  596.         }
  597.  
  598.  
  599.     default:
  600.         // do any application-specific menu handling
  601.         HandleApplicationMenu(MENU_IDENTIFIER(myMenuID, myMenuItem));
  602.         break;
  603.         
  604.     }    // switch (myMenuID)
  605.     
  606.     HiliteMenu(0);
  607. }
  608.  
  609.  
  610. //////////
  611. //
  612. // AdjustMenus
  613. // Adjust the application's File and Edit menus.
  614. //
  615. //////////
  616.  
  617. void AdjustMenus (void)
  618. {
  619.     WindowRef            myWindow = NULL;
  620.     WindowObject        myWindowObject = NULL;
  621.     MovieController        myMC = NULL;
  622.     MenuHandle            myMenu;
  623.  
  624.     myWindow = FrontWindow();
  625.     
  626.     if (myWindow != NULL)
  627.         myWindowObject = GetWindowObjectFromWindow(myWindow);
  628.     
  629.     if (myWindowObject != NULL)
  630.         myMC = (**myWindowObject).fController;
  631.  
  632.     if (myWindow != NULL) {
  633.     
  634.         // handle the File menu's Close command
  635.         EnableItem(GetMenuHandle(mFile), iClose);
  636.         
  637.         if (myWindowObject != NULL) {
  638.         
  639.             // handle the File menu's Save As and Print commands
  640.             EnableItem(GetMenuHandle(mFile), iSaveAs);
  641.             EnableItem(GetMenuHandle(mFile), iPrint);
  642.         
  643.             // let the movie controller do the right thing for the Edit menu
  644.             if (myMC != NULL) {
  645.                 long    myFlags;
  646.             
  647.                 MCSetUpEditMenu(myMC, 0L, GetMenuHandle(mEdit));
  648.                 
  649.                 // MCSetUpEditMenu doesn't handle Select All, so we'll do it ourselves....
  650.                 MCGetControllerInfo(myMC, &myFlags);
  651.                 if (myFlags & mcInfoEditingEnabled)
  652.                     EnableItem(GetMenuHandle(mEdit), iSelectAll);
  653.                 else
  654.                     DisableItem(GetMenuHandle(mEdit), iSelectAll);
  655.             }
  656.             
  657.             // handle the File menu's Save menu command
  658.             if ((**myWindowObject).fDirty)
  659.                 EnableItem(GetMenuHandle(mFile), iSave);
  660.             else
  661.                 DisableItem(GetMenuHandle(mFile), iSave);
  662.         } else {
  663.             // handle the File menu's Save As and Print commands
  664.             DisableItem(GetMenuHandle(mFile), iSaveAs);
  665.             DisableItem(GetMenuHandle(mFile), iPrint);
  666.         }
  667.         
  668.     } else {
  669.         // handle the File menu
  670.         myMenu = GetMenuHandle(mFile);
  671.         DisableItem(myMenu, iSave);
  672.         DisableItem(myMenu, iSaveAs);
  673.         DisableItem(myMenu, iClose);
  674.         DisableItem(myMenu, iPrint);
  675.         
  676.         // handle the Edit menu
  677.         myMenu = GetMenuHandle(mEdit);
  678.         DisableItem(myMenu, iCut);
  679.         DisableItem(myMenu, iCopy);
  680.         DisableItem(myMenu, iPaste);
  681.         DisableItem(myMenu, iUndo);
  682.         DisableItem(myMenu, iClear);
  683.         DisableItem(myMenu, iSelectAll);
  684.     }
  685.     
  686.     AdjustApplicationMenus(myWindow, NULL);                    // adjust any app-specific menus as well
  687. }
  688.  
  689.  
  690. //////////
  691. //
  692. // HandleKeyPress
  693. // Handle key presses. This is modelled on Inside Macintosh: Macintosh Toolbox Essentials, p. 3-78.
  694. //
  695. //////////
  696.  
  697. void HandleKeyPress (EventRecord *theEvent)
  698. {
  699.     char        myKey;
  700.     
  701.     myKey = theEvent->message & charCodeMask;
  702.     
  703.     if (theEvent->modifiers & cmdKey) {
  704.         // if the command key is down, it must be a keyboard shortcut for a menu selection;
  705.         // adjust the menus and find the menu command that the shortcut picks out
  706.         AdjustMenus();
  707.         HandleMenuCommand(MenuKey(myKey));
  708.     } else {
  709.         // otherwise, we'll assume it's meant for our application
  710.         HandleApplicationKeyPress(myKey);
  711.     }
  712. }
  713.  
  714.  
  715. //////////
  716. //
  717. // QuitFramework
  718. // Do any framework-specific shut-down.
  719. //
  720. //////////
  721.  
  722. void QuitFramework (void)
  723. {
  724.     WindowReference            myWindow;
  725.     WindowReference            myNextWindow;
  726.  
  727.     // set quit flag, so we exit the event loop the next time thru
  728.     gQuitFlag = true;
  729.     
  730.     // do any application-specific shutdown: before destroying any open windows
  731.     StopApplication(kStopAppPhase_BeforeDestroyWindows);
  732.     
  733.     // walk the window list and destroy any open windows
  734.     myWindow = GetFrontAppWindow();
  735.     while (myWindow != NULL) {
  736.         myNextWindow = GetNextAppWindow(myWindow);
  737.         DoDestroyMovieWindow(myWindow);
  738.         myWindow = myNextWindow;
  739.     }
  740.     
  741.     // test the quit flag; a call to DoDestroyMovieWindow may have reset it
  742.     if (!gQuitFlag)
  743.         return; 
  744.     
  745.     // do any application-specific shutdown: after destroying any open windows
  746.     StopApplication(kStopAppPhase_AfterDestroyWindows);
  747.     
  748.     // release the grow zone memory
  749.     DisposeHandle(gEmergencyMemory);
  750. }
  751.  
  752.  
  753. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  754. //
  755. // Framework utilities.
  756. //
  757. // The framework uses the following functions to create movies and handle dialog boxes. You probably won't
  758. // need to use them directly.
  759. //
  760. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  761.  
  762. //////////
  763. //
  764. // DoCreateNewMovie
  765. // Create a new movie in a window; returns true if successful.
  766. //
  767. // NOTE: There are several user interface issues that are blissfully ignored by this routine,
  768. // principally the preferred names and the on-screen locations of the new windows. 
  769. //
  770. //////////
  771.  
  772. Boolean DoCreateNewMovie (void)
  773. {
  774.     Movie                myMovie = NULL;
  775.     FSSpec                myFSSpec;
  776.     StringPtr             myName = QTUtils_ConvertCToPascalString(kNewMovieName);
  777.     
  778.     myMovie = NewMovie(newMovieActive);
  779.     if (myMovie == NULL)
  780.         return(false);
  781.     
  782.     // create a default FSSpec
  783.     FSMakeFSSpec(0, 0L, myName, &myFSSpec);
  784.     
  785.     free(myName);
  786.     
  787.     return(DoCreateMovieWindow(myMovie, &myFSSpec));
  788. }
  789.  
  790.  
  791. //////////
  792. //
  793. // SetupMovieWindowWithController
  794. // Configure the movie controller.
  795. //
  796. //////////
  797.  
  798. MovieController SetupMovieWindowWithController (Movie theMovie, WindowReference theWindow, Boolean theMoveWindow)
  799. {
  800.     MovieController            myMC;
  801.     Rect                    myRect;
  802.     WindowObject            myWindowObject;
  803.     GrafPtr                    mySavedPort;
  804.     short                    myMovieWidth;
  805.     short                    myMovieHeight;
  806.     
  807.     myWindowObject = GetWindowObjectFromWindow(theWindow);        // get our window specific data
  808.  
  809.     GetPort(&mySavedPort);
  810.     MacSetPort((GrafPtr)theWindow);
  811.     
  812.     // resize the movie bounding rect and offset to 0,0
  813.     GetMovieBox(theMovie, &myRect);
  814.     MacOffsetRect(&myRect, -myRect.left, -myRect.top);
  815.     SetMovieBox(theMovie, &myRect);
  816.     AlignWindow((WindowPtr)theWindow, false, &myRect, NULL);
  817.  
  818.     // create the movie controller
  819.     myMC = NewMovieController(theMovie, &myRect, gMCFlags);
  820.     if (myMC == NULL)
  821.         return(NULL);
  822.         
  823.     // enable the default movie controller editing
  824.     MCEnableEditing(myMC, true);
  825.         
  826.     // suppress movie badge
  827.     MCDoAction(myMC, mcActionSetUseBadge, (void *)false);
  828.  
  829.     MCGetControllerBoundsRect(myMC, &myRect);
  830.     
  831.     // add grow box for the movie controller
  832.     MCDoAction(myMC, mcActionSetGrowBoxBounds, &gLimitRect);
  833.     
  834.     // set the initial looping state of the movie; this is a nice touch
  835.     QTUtils_SetLoopingStateFromFile(theMovie, myMC);
  836.     
  837.     // install an action filter that does any application-specific mc action processing
  838.     MCSetActionFilterWithRefCon(myMC, NewMCActionFilterWithRefConProc(ApplicationMCActionFilterProc), (long)myWindowObject);
  839.                                                     
  840.     // see if the bounding rects are sane
  841.     myMovieWidth = myRect.right - myRect.left;
  842.     myMovieHeight = myRect.bottom - myRect.top;
  843.     
  844.     // resize the window
  845.     SizeWindow(theWindow, myMovieWidth, myMovieHeight, true);
  846.     if (theMoveWindow)
  847.         MoveWindow(theWindow, kDefaultX, kDefaultY, false);
  848.  
  849.     MacSetPort(mySavedPort);
  850.  
  851.     // add any application-specific controller functionality
  852.     AddControllerFunctionality(myMC);
  853.  
  854.     return(myMC);
  855. }
  856.  
  857.  
  858. //////////
  859. //
  860. // DoCreateMovieWindow
  861. // Open a movie in a new movie window; returns true if successful.
  862. //
  863. // This function is called from several places in our framework. The following combinations are possible:
  864. //    * theMovie == NULL, theFSSpec == NULL: no movie, no file; elicit a movie file from user and open it
  865. //    * theMovie != NULL, theFSSpec == NULL: new movie, no file (yet)
  866. //    * theMovie == NULL, theFSSpec != NULL: no movie, but we have an FSSpec; so just open the specified movie file
  867. //    * theMovie != NULL, theFSSpec != NULL: new movie, theFSSpec contains (at least) the movie name
  868. //
  869. //////////
  870.  
  871. Boolean DoCreateMovieWindow (Movie theMovie, FSSpec *theFSSpec)
  872. {
  873.     WindowObject        myWindowObject = NULL;
  874.     MovieController        myMC = NULL;
  875.     WindowReference        myWindow = NULL;
  876.     FSSpec                myFSSpec;
  877.     Movie                myMovie = NULL;
  878.     short                myRefNum = kInvalidFileRefNum;
  879.     short                myResID = 0;
  880.     SFTypeList            myTypeList = {kQTFileTypeMovie, 0, 0, 0};
  881.     StandardFileReply    myReply;
  882.     Rect                 myRect = gDefaultWindowRect;
  883.     GrafPtr                mySavedPort;
  884.     OSErr                myErr = noErr;
  885.  
  886.     // get the current port; we may need to restore it if we cannot successfully create a new window
  887.     GetPort(&mySavedPort);
  888.     
  889.     // if we got neither a movie nor an FSSpec passed in, prompt the user for a movie file
  890.     if ((theMovie == NULL) && (theFSSpec == NULL)) {
  891.     
  892.         StandardGetFilePreview(NULL, 1, myTypeList, &myReply);
  893.         if (!myReply.sfGood)
  894.             goto bail;
  895.         
  896.         // make an FSSpec record
  897.         FSMakeFSSpec(myReply.sfFile.vRefNum, myReply.sfFile.parID, myReply.sfFile.name, &myFSSpec);
  898.     }
  899.  
  900.     // if we got an FSSpec passed in, copy it into myFSSpec
  901.     if (theFSSpec != NULL) {
  902.     
  903.         // make an FSSpec record
  904.         FSMakeFSSpec(theFSSpec->vRefNum, theFSSpec->parID, theFSSpec->name, &myFSSpec);        
  905.     }
  906.  
  907.     // if we got no movie passed in, read one from the specified file
  908.     if (theMovie == NULL) {
  909.  
  910.         // ideally, we'd like read and write permission, but we'll settle for read-only permission
  911.         myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdWrPerm);
  912.         if (myErr != noErr)
  913.             myErr = OpenMovieFile(&myFSSpec, &myRefNum, fsRdPerm);
  914.  
  915.         // if we couldn't open the file with even just read-only permission, bail....
  916.         if (myErr != noErr)
  917.             goto bail;
  918.  
  919.         // now fetch the first movie from the file
  920.         myResID = 0;
  921.         myErr = NewMovieFromFile(&myMovie, myRefNum, &myResID, NULL, newMovieActive, NULL);
  922.         if (myErr != noErr)
  923.             goto bail;
  924.         
  925.         // we will allow the user to edit our files, so we keep the movie file open
  926.         // CloseMovieFile(myRefNum);
  927.         
  928.     } else {
  929.         myMovie = theMovie;
  930.     }
  931.  
  932.     //////////
  933.     //
  934.     // at this point, myMovie is an open movie, but myFSSpec may or may not be a valid FSSpec
  935.     //
  936.     //////////
  937.     
  938.     // set the default progress procedure for the movie
  939.     SetMovieProgressProc(myMovie, (MovieProgressUPP)-1, 0);
  940.         
  941.     // create a new window to display the movie in
  942.     myWindow = CreateMovieWindow(&myRect, gWindowTitle);
  943.     if (myWindow == NULL)
  944.         goto bail;
  945.     
  946.     MacSetPort(GetPortFromWindowReference(myWindow));
  947.     myWindowObject = CreateWindowObject(myWindow);
  948.     if (myWindowObject == NULL)
  949.         goto bail;
  950.     
  951.     // set the window title
  952.     SetWTitle(myWindow, myFSSpec.name);
  953.  
  954.     // make sure the movie uses the window GWorld in all situations
  955.     SetMovieGWorld(myMovie, (CGrafPtr)GetPortFromWindowReference(myWindow), GetGWorldDevice((CGrafPtr)GetPortFromWindowReference(myWindow)));
  956.  
  957.     // create and configure the movie controller
  958.     myMC = SetupMovieWindowWithController(myMovie, myWindow, true);
  959.         
  960.     // store movie info in the window record
  961.     (**myWindowObject).fMovie = myMovie;
  962.     (**myWindowObject).fController = myMC;
  963.     (**myWindowObject).fFileResID = myResID;
  964.     (**myWindowObject).fFileRefNum = myRefNum;
  965.     (**myWindowObject).fCanResizeWindow = true;
  966.     (**myWindowObject).fDirty = false;
  967.     (**myWindowObject).fInstance = NULL;
  968.     (**myWindowObject).fAppData = NULL;
  969.     (**myWindowObject).fFileFSSpec = myFSSpec;
  970.     
  971.     // do any application-specific window object initialization
  972.     InitApplicationWindowObject(myWindowObject);
  973.     
  974.     // size the window to fit the movie and controller
  975.     SizeWindowToMovie(myWindowObject);
  976.  
  977.     // set the movie's play hints to allow dynamic resizing
  978.     SetMoviePlayHints(myMovie, hintsAllowDynamicResize, hintsAllowDynamicResize);
  979.  
  980.     // show the window
  981.     ShowWindow(myWindow);
  982.     SelectWindow(myWindow);                                // make it front-most, since it's just been created
  983.     InvalRect(&((GrafPtr)myWindow)->portRect);
  984.     
  985.     // if the movie is a streamed movie, then start it playing immediately
  986.     if (QTUtils_IsStreamedMovie(myMovie))
  987.         MCDoAction(myMC, mcActionPrerollAndPlay, (void *)GetMoviePreferredRate(myMovie));
  988.         
  989.     return(true);
  990.     
  991. bail:
  992.     if (myWindow != NULL)
  993.         DisposeWindow(myWindow);
  994.         
  995.     if (myMC != NULL)
  996.         DisposeMovieController(myMC);
  997.         
  998.     if (myMovie != NULL)
  999.         DisposeMovie(myMovie);
  1000.         
  1001.     if (myRefNum != 0)
  1002.         CloseMovieFile(myRefNum);
  1003.  
  1004.     MacSetPort(mySavedPort);    // restore the port that was active when this function was called
  1005.  
  1006.     return(false);
  1007. }
  1008.  
  1009.  
  1010. //////////
  1011. //
  1012. // DoDestroyMovieWindow
  1013. // Close the specified movie window.
  1014. //
  1015. //////////
  1016.  
  1017. void DoDestroyMovieWindow (WindowReference theWindow)
  1018. {
  1019.     Movie                 myMovie = NULL;
  1020.     MovieController        myMC = NULL;
  1021.     WindowObject        myWindowObject = NULL;
  1022.     
  1023.     // get the window object associated with the specified window
  1024.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1025.     if (myWindowObject == NULL) {
  1026.         // if the window passed in isn't a movie window, just dispose of it and return
  1027.         if (theWindow != NULL) {
  1028.             DisposeWindow(theWindow);
  1029.             theWindow = NULL;
  1030.         }
  1031.         return;
  1032.     }
  1033.     
  1034.     // if the window's data is "dirty", give the user a chance to save it;
  1035.     // this is modeled on Inside Macintosh: Macintosh Toolbox Essentials, pp. 4-62f.
  1036.     if ((**myWindowObject).fDirty) {
  1037.         Str255            myString;
  1038.         short            myItem;
  1039.         short             mySavedResFile;
  1040.         
  1041.         // get the current resource file and set the application's resource file
  1042.         mySavedResFile = CurResFile();
  1043.         UseResFile(gAppResFile);
  1044.  
  1045.         // get the title of the window
  1046.         GetWTitle(theWindow, myString);
  1047.         
  1048.         // insert the application's name and the window title into the dialog box text
  1049.         ParamText(gAppName, myString, NULL, NULL);
  1050.         
  1051.         // display the "Save changes" dialog box
  1052.         myItem = CautionAlert(kSaveDialogID, gModalFilterUPP);
  1053.         
  1054.         UseResFile(mySavedResFile);                    // restore the original resource file
  1055.         
  1056.         switch (myItem) {
  1057.             case kSaveChanges:
  1058.                 // save the data in the window
  1059.                 DoUpdateMovieFile(theWindow);
  1060.                 break;
  1061.                 
  1062.             case kDontSaveChanges:
  1063.                 // discard any unsaved changes (that is, don't do anything)
  1064.                 break;
  1065.                 
  1066.             case kCancelClose:
  1067.                 // do not close the window, and do not quit the application
  1068.                 gQuitFlag = false;
  1069.                 return;
  1070.         }
  1071.     }
  1072.  
  1073.     myMC = (**myWindowObject).fController;
  1074.     myMovie = (**myWindowObject).fMovie;
  1075.             
  1076.     // remove our mcAction filter function
  1077.     MCSetActionFilterWithRefCon(myMC, NULL, NULL);
  1078.  
  1079.     // close the movie file
  1080.     if ((**myWindowObject).fFileRefNum != kInvalidFileRefNum) {
  1081.         CloseMovieFile((**myWindowObject).fFileRefNum);
  1082.         (**myWindowObject).fFileRefNum = kInvalidFileRefNum;
  1083.     }
  1084.     
  1085.     // order is important here; according to Inside Macintosh: QuickTime, p. 2-96:
  1086.     // "Do not dispose of a movie if it has any special clients--for example,
  1087.     // if it has an attached movie controller component.
  1088.     // Only dispose of the movie after any clients are done with it."
  1089.     if (myMC != NULL)
  1090.         DisposeMovieController(myMC);
  1091.  
  1092.     if (myMovie != NULL)
  1093.         DisposeMovie(myMovie);
  1094.  
  1095.     // do any application-specific window clean-up
  1096.     RemoveApplicationWindowObject(myWindowObject);
  1097.     
  1098.     DisposeHandle((Handle)myWindowObject);
  1099.     DisposeWindow(theWindow);
  1100. }
  1101.  
  1102.  
  1103. //////////
  1104. //
  1105. // DoSaveAsMovieFile
  1106. // Save the movie in the specified window under a new name.
  1107. //
  1108. // Human interface guidelines for "Save As..." dictate that, if the user selects a new file name
  1109. // for the current movie, then that new file shall become the active one. This means that we need
  1110. // to close the current movie file and open the new one.
  1111. //
  1112. //////////
  1113.  
  1114. OSErr DoSaveAsMovieFile (WindowReference theWindow)
  1115. {
  1116.     WindowObject        myWindowObject = NULL;
  1117.     Movie                 myMovie = NULL;
  1118.     StandardFileReply    mySFReply;
  1119.     StringPtr             myPrompt = QTUtils_ConvertCToPascalString(kSavePrompt);
  1120.     StringPtr             myFileName = QTUtils_ConvertCToPascalString(kSaveMovieFileName);
  1121.     OSErr                myErr = paramErr;
  1122.     
  1123.     // get the window object associated with the specified window
  1124.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1125.     if (myWindowObject == NULL)
  1126.         goto bail;
  1127.         
  1128.     myMovie = (**myWindowObject).fMovie;
  1129.     if (myMovie == NULL)
  1130.         goto bail;
  1131.         
  1132.     StandardPutFile(myPrompt, myFileName, &mySFReply); 
  1133.     if (mySFReply.sfGood) {
  1134.         Movie            myNewMovie = NULL;
  1135.         MovieController    myMC = NULL;
  1136.         long            myFlags;
  1137.         short            myRefNum = kInvalidFileRefNum;
  1138.         short            myResID = movieInDataForkResID;
  1139.         
  1140.         //////////
  1141.         //
  1142.         // we have a valid FSSpec for the new movie file; now we want to create a new movie file,
  1143.         // save the movie data into the new file, close the existing movie file, and then swap
  1144.         // the window object data
  1145.         //
  1146.         //////////
  1147.         
  1148.         // delete any existing file of that name
  1149.         if (mySFReply.sfReplacing) {
  1150.             myErr = DeleteMovieFile(&mySFReply.sfFile);
  1151.             if (myErr != noErr)
  1152.                 goto bail;
  1153.         }
  1154.         
  1155.         myFlags = createMovieFileDeleteCurFile | createMovieFileDontOpenFile | createMovieFileDontCreateMovie | createMovieFileDontCreateResFile;
  1156.         myErr = CreateMovieFile(&mySFReply.sfFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, NULL, NULL);
  1157.         if (myErr != noErr)
  1158.             goto bail;
  1159.         
  1160.         myErr = OpenMovieFile(&mySFReply.sfFile, &myRefNum, fsRdWrPerm);
  1161.         if (myErr != noErr)
  1162.             goto bail;
  1163.             
  1164.         // write existing movie's data into new movie file
  1165.         myErr = AddMovieResource(myMovie, myRefNum, &myResID, mySFReply.sfFile.name);
  1166.         if (myErr != noErr)
  1167.             goto bail;
  1168.  
  1169.         // get the new movie from the file
  1170.         myErr = NewMovieFromFile(&myNewMovie, myRefNum, &myResID, NULL, newMovieActive, NULL);        
  1171.         if (myErr != noErr)
  1172.             goto bail;
  1173.         
  1174.         // create a new movie controller
  1175.         myMC = SetupMovieWindowWithController(myNewMovie, theWindow, false);
  1176.         
  1177.         //////////
  1178.         //
  1179.         // if we got to here, we've successfully created a new movie file, and NewMovieFromFile has
  1180.         // returned the new movie to us; so we need to close down the current movie and install the
  1181.         // new movie in its place
  1182.         //
  1183.         //////////
  1184.         
  1185.         // close the existing movie file
  1186.         if ((**myWindowObject).fFileRefNum != kInvalidFileRefNum)
  1187.             CloseMovieFile((**myWindowObject).fFileRefNum);
  1188.         
  1189.         // dispose of the existing movie controller and movie resource
  1190.         DisposeMovieController((**myWindowObject).fController);
  1191.         DisposeMovie(myMovie);
  1192.         
  1193.         // keep track of the new info
  1194.         (**myWindowObject).fMovie = myNewMovie;
  1195.         (**myWindowObject).fController = myMC;
  1196.         (**myWindowObject).fFileFSSpec = mySFReply.sfFile;
  1197.         (**myWindowObject).fFileResID = myResID;
  1198.         (**myWindowObject).fFileRefNum = myRefNum;
  1199.         (**myWindowObject).fDirty = false;
  1200.  
  1201.         // make sure the movie uses the window GWorld in all situations
  1202.         SetMovieGWorld(myNewMovie, (CGrafPtr)GetPortFromWindowReference((**myWindowObject).fWindow), GetGWorldDevice((CGrafPtr)GetPortFromWindowReference((**myWindowObject).fWindow)));
  1203.  
  1204.         // set the window title
  1205.         SetWTitle(theWindow, mySFReply.sfFile.name);
  1206.     } else {
  1207.         myErr = userCanceledErr;
  1208.     }
  1209.  
  1210. bail:
  1211.     free(myPrompt);
  1212.     free(myFileName);
  1213.     
  1214.     return(myErr);
  1215. }
  1216.  
  1217.  
  1218. //////////
  1219. //
  1220. // DoUpdateMovieFile
  1221. // Update the file (if any) attached to the movie.
  1222. //
  1223. //////////
  1224.  
  1225. Boolean DoUpdateMovieFile (WindowReference theWindow)
  1226. {
  1227.     WindowObject        myWindowObject = NULL;
  1228.     Movie                 myMovie = NULL;
  1229.     OSErr                myErr = noErr;
  1230.     
  1231.     // get the window object associated with the specified window
  1232.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1233.     if (myWindowObject == NULL)
  1234.         return(false);
  1235.         
  1236.     myMovie = (**myWindowObject).fMovie;
  1237.     if (myMovie == NULL)
  1238.         return(false);
  1239.     
  1240.     // update the current volume setting
  1241.     QTUtils_UpdateMovieVolumeSetting(myMovie);
  1242.     
  1243.     if ((**myWindowObject).fFileRefNum == kInvalidFileRefNum)        // brand new movie, so no file attached to it
  1244.         myErr = DoSaveAsMovieFile(theWindow);
  1245.     else                                                            // we have an existing file; just update the movie resource
  1246.         myErr = UpdateMovieResource(myMovie, (**myWindowObject).fFileRefNum, (**myWindowObject).fFileResID, NULL);
  1247.     
  1248.     (**myWindowObject).fDirty = false;
  1249.  
  1250.     return(myErr == noErr);
  1251. }
  1252.  
  1253.  
  1254. //////////
  1255. //
  1256. // DoActivateWindow
  1257. // Activate or deactivate the specified window.
  1258. //
  1259. //////////
  1260.  
  1261. void DoActivateWindow (WindowReference theWindow, Boolean isBecomingActive)
  1262. {
  1263.     WindowObject         myWindowObject = NULL;
  1264.     MovieController        myMC = NULL;
  1265.     GrafPtr                mySavedPort = NULL;
  1266.     
  1267.     if (theWindow == NULL)
  1268.         return;
  1269.     
  1270.     GetPort(&mySavedPort);
  1271.     MacSetPort((GrafPtr)theWindow);
  1272.     
  1273.     // get the window object associated with the specified window
  1274.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1275.     if (myWindowObject != NULL) {
  1276.         myMC = (**myWindowObject).fController;
  1277.         if (myMC != NULL)
  1278.             MCActivate(myMC, theWindow, isBecomingActive);
  1279.     }
  1280.     
  1281.     MacSetPort(mySavedPort);
  1282. }
  1283.  
  1284.  
  1285. //////////
  1286. //
  1287. // StandardUserItemProcedure
  1288. // A standard user-item procedure to outline the OK button in a modal dialog.
  1289. //
  1290. //////////
  1291.  
  1292. PASCAL_RTN void StandardUserItemProcedure (DialogPtr theDialog, short theItem)
  1293. {
  1294. #pragma unused(theItem)
  1295.  
  1296.     short            myItemKind;        // for GetDialogItem
  1297.     Handle            myItemHandle;    // for GetDialogItem
  1298.     Rect            myItemRect;        // for GetDialogItem
  1299.  
  1300.     if (!gHasNewDialogCalls) {        // no need to do any of this if the new Dialog Manager calls are available
  1301.         GetDialogItem(theDialog, kStdOkItemIndex, &myItemKind, &myItemHandle, &myItemRect);        
  1302.         MacInsetRect(&myItemRect, -4, -4);
  1303.         PenSize(3, 3);
  1304.         FrameRoundRect(&myItemRect, 16, 16);
  1305.         PenSize(1, 1);
  1306.     }
  1307. }
  1308.  
  1309.  
  1310. //////////
  1311. //
  1312. // StandardModalDialogEventFilter
  1313. // A standard modal dialog event filter. 
  1314. //
  1315. //////////
  1316.  
  1317. PASCAL_RTN Boolean StandardModalDialogEventFilter (DialogPtr theDialog, EventRecord *theEvent, short *theItemHit)
  1318. {
  1319.     Boolean                myEventHandled = false;
  1320.     short                myItemKind;            // for GetDialogItem
  1321.     Handle                myItemHandle;        // for GetDialogItem
  1322.     Rect                myItemRect;            // for GetDialogItem
  1323.     unsigned long        myTicks;            // for Delay
  1324.     char                myKey;        
  1325.     WindowReference        myWindow = NULL;
  1326.     ModalFilterUPP        myStdModalProc;        // the OS's standard filter procedure
  1327.     short                myPart;    
  1328.     OSErr                myErr = noErr;
  1329.         
  1330.     switch (theEvent->what) {
  1331.         case updateEvt:
  1332.             // update the specified window, if it's behind the modal dialog
  1333.             myWindow = (WindowReference)theEvent->message;
  1334.             if ((myWindow != NULL) && (myWindow != theDialog)) {
  1335.                 DoUpdateWindow(myWindow, &(**(myWindow->visRgn)).rgnBBox);
  1336.                 myEventHandled = false;        // so sayeth IM
  1337.             }
  1338.             break;
  1339.  
  1340.         case nullEvent:
  1341.             // do idle-time processing for all open windows in our window list
  1342.             myWindow = FrontWindow();
  1343.             while (myWindow != NULL) {
  1344.                 if (gAppInForeground)
  1345.                     DoIdle(myWindow);
  1346.                     
  1347.                 myWindow = (WindowPtr)(((WindowRecord*)myWindow)->nextWindow);
  1348.             }
  1349.             
  1350.             myEventHandled = false;
  1351.             break;
  1352.             
  1353.         case keyDown:
  1354.         case autoKey:
  1355.             // if new Dialog Manager calls are NOT available, handle certain key presses
  1356.             if (!gHasNewDialogCalls) {
  1357.                 // first, map Command-period to Escape key...
  1358.                 myKey = theEvent->message & charCodeMask;
  1359.                 if (theEvent->modifiers & cmdKey)
  1360.                     if (myKey == kPeriod)
  1361.                         myKey = kEscapeKey;
  1362.                         
  1363.                 // ...then, handle the standard keyboard equivalents of OK and Cancel buttons
  1364.                 switch (myKey) {
  1365.                     case kReturnKey:
  1366.                     case kEnterKey:
  1367.                         *theItemHit = kStdOkItemIndex;
  1368.                         GetDialogItem(theDialog, kStdOkItemIndex, &myItemKind, &myItemHandle, &myItemRect);
  1369.                         HiliteControl((ControlHandle)myItemHandle, kControlButtonPart);
  1370.                         Delay(kMyButtonDelay, &myTicks);
  1371.                         HiliteControl((ControlHandle)myItemHandle, false);
  1372.                         myEventHandled = true;
  1373.                         break;
  1374.                     case kEscapeKey:
  1375.                         *theItemHit = kStdCancelItemIndex;
  1376.                         GetDialogItem(theDialog, kStdCancelItemIndex, &myItemKind, &myItemHandle, &myItemRect);
  1377.                         HiliteControl((ControlHandle)myItemHandle, kControlButtonPart);
  1378.                         Delay(kMyButtonDelay, &myTicks);
  1379.                         HiliteControl((ControlHandle)myItemHandle, false);
  1380.                         myEventHandled = true;
  1381.                         break;
  1382.                     default:
  1383.                         break;
  1384.                 }
  1385.             }
  1386.             break;
  1387.             
  1388.         case mouseDown:
  1389.             myPart = FindWindow(theEvent->where, &myWindow);
  1390.             if (myPart == inDrag) {
  1391.                 Rect        myScreenRect;
  1392.                 
  1393.                 myScreenRect = (**GetGrayRgn()).rgnBBox;
  1394.                 DragWindow(myWindow, theEvent->where, &myScreenRect);
  1395.                 myEventHandled = true;
  1396.             }
  1397.             break;
  1398.             
  1399.         default:
  1400.             myEventHandled = false;
  1401.             break;
  1402.     }    
  1403.     
  1404.     // let the OS's standard filter proc handle the event, if it hasn't already been handled
  1405.     if (gHasNewDialogCalls && (myEventHandled == false)) {
  1406.         myErr = GetStdFilterProc(&myStdModalProc);
  1407.         if (myErr == noErr)
  1408.             myEventHandled = CallModalFilterProc(myStdModalProc, theDialog, theEvent, theItemHit);
  1409.     }
  1410.     
  1411.     return(myEventHandled);
  1412. }
  1413.  
  1414.  
  1415. //////////
  1416. //
  1417. // CheckMovieControllers
  1418. // Let all movie controllers have a chance to process the event.
  1419. //
  1420. // Returns true if the event was handled by some movie controller, false otherwise
  1421. //
  1422. //////////
  1423.  
  1424. Boolean CheckMovieControllers (EventRecord *theEvent)
  1425. {    
  1426.     WindowPtr                myWindow;
  1427.     WindowObject            myWindowObject;
  1428.     MovieController            myMC;
  1429.     
  1430.     myWindow = GetFrontMovieWindow();
  1431.     while (myWindow != NULL) {
  1432.          myWindowObject = GetWindowObjectFromWindow(myWindow);
  1433.         if (myWindowObject != NULL) {
  1434.             myMC = (**myWindowObject).fController;
  1435.             if (myMC != NULL)
  1436.                 if (MCIsPlayerEvent(myMC, theEvent))
  1437.                     return(true);
  1438.         }
  1439.         
  1440.         myWindow = GetNextMovieWindow(myWindow);
  1441.     }
  1442.     
  1443.     return(false);
  1444. }
  1445.  
  1446.  
  1447. //////////
  1448. //
  1449. // IsAppWindow
  1450. // Does the specified window belong to our application?
  1451. //
  1452. //////////
  1453.  
  1454. Boolean IsAppWindow (WindowReference theWindow)
  1455. {
  1456.     short            myWindowKind;
  1457.     
  1458.     if (theWindow == NULL) {
  1459.         return(false);
  1460.     } else {
  1461.         myWindowKind = ((WindowPeek)theWindow)->windowKind;
  1462.         return((myWindowKind >= userKind) || (myWindowKind == dialogKind));
  1463.     }
  1464. }
  1465.  
  1466.  
  1467. //////////
  1468. //
  1469. // IsDocWindow
  1470. // Is the specified window a document window (having a WindowObject refcon)?
  1471. //
  1472. //////////
  1473.  
  1474. Boolean IsDocWindow (WindowReference theWindow)
  1475. {
  1476.     short            myWindowKind;
  1477.     
  1478.     if (theWindow == NULL) {
  1479.         return(false);
  1480.     } else {
  1481.         myWindowKind = ((WindowPeek)theWindow)->windowKind;
  1482.         return(myWindowKind >= userKind);
  1483.     }
  1484. }
  1485.  
  1486.  
  1487. //////////
  1488. //
  1489. // CreateWindowObject
  1490. // Create a window object for the specified window.
  1491. //
  1492. //////////
  1493.  
  1494. WindowObject CreateWindowObject (WindowReference theWindow)
  1495. {
  1496.     WindowObject    myWindowObject = NULL;
  1497.     
  1498.     myWindowObject = (WindowObject)NewHandleClear(sizeof(WindowObjectRecord));
  1499.     
  1500.     if (myWindowObject != NULL) {
  1501.         (**myWindowObject).fWindow = theWindow;
  1502.         (**myWindowObject).fController = NULL;
  1503.         (**myWindowObject).fObjectType = kMovieControllerObject;
  1504.         (**myWindowObject).fInstance = NULL;
  1505.         (**myWindowObject).fDirty = false;
  1506.         (**myWindowObject).fAppData = NULL;
  1507.     }
  1508.         
  1509.     SetWRefCon(theWindow, (long)myWindowObject);        // store a ref to the record in the window
  1510.     
  1511.     return(myWindowObject);
  1512. }
  1513.  
  1514.  
  1515. //////////
  1516. //
  1517. // SizeWindowToMovie
  1518. // Set the window size to exactly fit the movie and controller (if visible).
  1519. //
  1520. //////////
  1521.  
  1522. void SizeWindowToMovie (WindowObject theWindowObject)
  1523. {
  1524.     Rect                myMovieBounds;
  1525.     MovieController        myMC = NULL;
  1526.     Movie                myMovie = NULL;
  1527.     
  1528.     if (theWindowObject == NULL)
  1529.         return;
  1530.         
  1531.     myMC = (**theWindowObject).fController;
  1532.     myMovie = (**theWindowObject).fMovie;
  1533.  
  1534.     if (MCGetVisible(myMC))
  1535.         MCGetControllerBoundsRect(myMC, &myMovieBounds);
  1536.     else
  1537.         GetMovieBox(myMovie, &myMovieBounds);
  1538.     
  1539.     // make sure that the movie has a non-zero width;
  1540.     // a zero height is okay (for example, with a music movie with no controller bar)
  1541.     if (myMovieBounds.right - myMovieBounds.left == 0) {
  1542.         myMovieBounds.left = 0;
  1543.         myMovieBounds.right = GetWindowWidth((**theWindowObject).fWindow);
  1544.     }
  1545.         
  1546.     SizeWindow(GetPortFromWindowReference((**theWindowObject).fWindow),
  1547.                                             myMovieBounds.right - myMovieBounds.left,
  1548.                                             myMovieBounds.bottom - myMovieBounds.top,
  1549.                                             true);
  1550. }
  1551.  
  1552.  
  1553. //////////
  1554. //
  1555. // ShowAboutBox
  1556. // Display and manage the About dialog box.
  1557. //
  1558. //////////
  1559.  
  1560. void ShowAboutBox (void)
  1561. {
  1562.     DialogPtr            myDialog = NULL;
  1563.     WindowReference        myWindow = NULL;
  1564.     short                 myItem;
  1565.     short                 mySavedResFile;
  1566.     GrafPtr                mySavedPort;
  1567.     short                myItemKind;
  1568.     Handle                myItemHandle;
  1569.     Rect                myItemRect;
  1570.     
  1571.     // get the current resource file and port
  1572.     mySavedResFile = CurResFile();
  1573.     GetPort(&mySavedPort);
  1574.     
  1575.     // set the application's resource file;
  1576.     // otherwise, we'd get the dialog's resources from the current resource file,
  1577.     // which might not be the correct one....
  1578.     UseResFile(gAppResFile);
  1579.     
  1580.     // deactivate any frontmost movie window
  1581.     myWindow = GetFrontMovieWindow();
  1582.     if (myWindow != NULL)
  1583.         DoActivateWindow(myWindow, false);
  1584.     
  1585.     myDialog = GetNewDialog(kAboutBoxID, NULL, (WindowPtr)-1L);
  1586.     if (myDialog == NULL)
  1587.         goto bail;
  1588.         
  1589.     MacSetPort((GrafPtr)myDialog);
  1590.         
  1591.     if (gHasNewDialogCalls)
  1592.         SetDialogDefaultItem(myDialog, kStdOkItemIndex);
  1593.     
  1594.     // make sure that the OK button is outlined in bold, even if new Dialog Manager calls not available
  1595.     GetDialogItem(myDialog, kOKButtonUserItem, &myItemKind, &myItemHandle, &myItemRect);
  1596.     SetDialogItem(myDialog, kOKButtonUserItem, myItemKind, (Handle)gUserItemProcUPP, &myItemRect);
  1597.  
  1598.     // display and handle events in the dialog box until the user clicks OK
  1599.     do {
  1600.         ModalDialog(gModalFilterUPP, &myItem);
  1601.     } while (myItem != kStdOkItemIndex);
  1602.     
  1603. bail:
  1604.     // restore the previous resource file and port
  1605.     MacSetPort(mySavedPort);
  1606.     UseResFile(mySavedResFile);
  1607.     
  1608.     if (myDialog != NULL)
  1609.         DisposeDialog(myDialog);
  1610. }
  1611.  
  1612.  
  1613. //////////
  1614. //
  1615. // ShowWarning
  1616. // Display a warning box.
  1617. //
  1618. //////////
  1619.  
  1620. void ShowWarning (Str255 theMessage, OSErr theErr)
  1621. {
  1622.     Str255                myString;
  1623.     short                 mySavedResFile;
  1624.     
  1625.     // get the current resource file and set the application's resource file
  1626.     mySavedResFile = CurResFile();
  1627.     UseResFile(gAppResFile);
  1628.  
  1629.     NumToString(theErr, myString);
  1630.     ParamText("\pWarning!", theMessage, theErr ? myString: NULL, NULL);
  1631.     Alert(kAlertErrorID, gModalFilterUPP);
  1632.     
  1633.     // restore the original resource file
  1634.     UseResFile(mySavedResFile);
  1635. }
  1636.  
  1637.  
  1638. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1639. //
  1640. // Window walking utilities.
  1641. //
  1642. // Use these two functions to iterate through all open movie windows belonging to the application.
  1643. //
  1644. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1645.  
  1646. //////////
  1647. //
  1648. // GetFrontMovieWindow
  1649. // Return a reference to the frontmost movie window.
  1650. //
  1651. //////////
  1652.  
  1653. WindowReference GetFrontMovieWindow (void)
  1654. {
  1655.     WindowReference            myWindow = GetFrontAppWindow();
  1656.     
  1657.     while ((myWindow != NULL) && (GetWindowObjectFromWindow(myWindow) == NULL))
  1658.         myWindow = GetNextAppWindow(myWindow);
  1659.  
  1660.     return(myWindow);
  1661. }
  1662.  
  1663.  
  1664. //////////
  1665. //
  1666. // GetNextMovieWindow
  1667. // Return a reference to the next movie window.
  1668. //
  1669. //////////
  1670.  
  1671. WindowReference GetNextMovieWindow (WindowReference theWindow)
  1672. {
  1673.     WindowReference            myWindow = GetNextAppWindow(theWindow);
  1674.  
  1675.     while ((myWindow != NULL) && (GetWindowObjectFromWindow(myWindow) == NULL))
  1676.         myWindow = GetNextAppWindow(myWindow);
  1677.  
  1678.     return(myWindow);
  1679. }
  1680.  
  1681.  
  1682. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1683. //
  1684. // Data retrieval utilities.
  1685. //
  1686. // Use the following functions to retrieve the window object, the application-specific data, or the movie
  1687. // controller that is associated with a window.
  1688. //
  1689. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1690.  
  1691. //////////
  1692. //
  1693. // GetWindowObjectFromFrontWindow
  1694. // Get the window object associated with the front window.
  1695. //
  1696. //////////
  1697.  
  1698. WindowObject GetWindowObjectFromFrontWindow (void)
  1699. {
  1700.     return(GetWindowObjectFromWindow(FrontWindow()));
  1701. }
  1702.  
  1703.  
  1704. //////////
  1705. //
  1706. // GetWindowObjectFromWindow
  1707. // Get the window object associated with the specified window.
  1708. //
  1709. //////////
  1710.  
  1711. WindowObject GetWindowObjectFromWindow (WindowReference theWindow)
  1712. {
  1713.     WindowObject        myWindowObject = NULL;
  1714.  
  1715.     if (!IsAppWindow(theWindow))
  1716.         return(NULL);
  1717.             
  1718.     myWindowObject = (WindowObject)GetWRefCon(theWindow);
  1719.  
  1720.     // make sure this is a window object
  1721.     if (!IsWindowObjectOurs(myWindowObject))
  1722.         return(NULL);
  1723.         
  1724.     return(myWindowObject);
  1725. }
  1726.  
  1727.  
  1728. //////////
  1729. //
  1730. // GetMCFromFrontWindow
  1731. // Get the movie controller (if any) associated with the front window.
  1732. //
  1733. //////////
  1734.  
  1735. MovieController GetMCFromFrontWindow (void)
  1736. {
  1737.     MovieController     myMC = NULL;
  1738.     WindowObject        myWindowObject = NULL;
  1739.         
  1740.     myWindowObject = GetWindowObjectFromFrontWindow();
  1741.     if (myWindowObject != NULL)
  1742.         myMC = (**myWindowObject).fController;
  1743.         
  1744.     return(myMC);
  1745. }
  1746.  
  1747.  
  1748. //////////
  1749. //
  1750. // GetMCFromWindow
  1751. // Get the movie controller (if any) associated with the specified window.
  1752. //
  1753. //////////
  1754.  
  1755. MovieController GetMCFromWindow (WindowReference theWindow)
  1756. {
  1757.     MovieController     myMC = NULL;
  1758.     WindowObject        myWindowObject = NULL;
  1759.         
  1760.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1761.     if (myWindowObject != NULL)
  1762.         myMC = (**myWindowObject).fController;
  1763.         
  1764.     return(myMC);
  1765. }
  1766.  
  1767.  
  1768. //////////
  1769. //
  1770. // GetQTVRInstanceFromFrontWindow
  1771. // Get the QTVRInstance (if any) associated with the front window.
  1772. //
  1773. //////////
  1774.  
  1775. QTVRInstance GetQTVRInstanceFromFrontWindow (void)
  1776. {
  1777.     QTVRInstance         myInstance = NULL;
  1778.     WindowObject        myWindowObject = NULL;
  1779.  
  1780.     myWindowObject = GetWindowObjectFromFrontWindow();
  1781.     if (myWindowObject != NULL)
  1782.         myInstance = (**myWindowObject).fInstance;
  1783.         
  1784.     return(myInstance);
  1785. }
  1786.  
  1787.  
  1788. //////////
  1789. //
  1790. // GetAppDataFromFrontWindow
  1791. // Get the application-specific data associated with the front window.
  1792. //
  1793. //////////
  1794.  
  1795. Handle GetAppDataFromFrontWindow (void)
  1796. {
  1797.     return(GetAppDataFromWindow(FrontWindow()));
  1798. }
  1799.  
  1800.  
  1801. //////////
  1802. //
  1803. // GetAppDataFromWindow
  1804. // Get the application-specific data associated with the specified window.
  1805. //
  1806. //////////
  1807.  
  1808. Handle GetAppDataFromWindow (WindowReference theWindow)
  1809. {
  1810.     WindowObject        myWindowObject = NULL;
  1811.     
  1812.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  1813.     if (myWindowObject == NULL)
  1814.         return(NULL);
  1815.     else
  1816.         return(GetAppDataFromWindowObject(myWindowObject));
  1817. }
  1818.  
  1819.  
  1820. //////////
  1821. //
  1822. // GetAppDataFromWindowObject
  1823. // Get the application-specific data associated with the specified window object.
  1824. //
  1825. //////////
  1826.  
  1827. Handle GetAppDataFromWindowObject (WindowObject theWindowObject)
  1828. {
  1829.     Handle                myAppData = NULL;
  1830.             
  1831.     // make sure this is a window object belonging to our application
  1832.     if (!IsWindowObjectOurs(theWindowObject))
  1833.         return(myAppData);
  1834.     
  1835.     // get the app data handle from the window object
  1836.     myAppData = (**theWindowObject).fAppData;
  1837.     
  1838.     return(myAppData);
  1839. }
  1840.  
  1841.  
  1842. //////////
  1843. //
  1844. // IsWindowObjectOurs
  1845. // Does the specified window object belong to our application?
  1846. //
  1847. //////////
  1848.  
  1849. Boolean IsWindowObjectOurs (WindowObject theWindowObject)
  1850. {
  1851.     OSType        myType = NULL;
  1852.  
  1853.     if ((theWindowObject == NULL) || (*theWindowObject == NULL))
  1854.         return(false);
  1855.         
  1856.     myType = (**theWindowObject).fObjectType;
  1857.     if (myType == kMovieControllerObject)
  1858.         return(true);
  1859.     else
  1860.         return(false);
  1861. }
  1862.  
  1863.  
  1864. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1865. //
  1866. // Miscellaneous utilities.
  1867. //
  1868. // Use the following functions to play beeps, manipulate menus, and do other miscellaneous things. These
  1869. // functions are intended for use in cross-platform code.
  1870. //
  1871. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1872.  
  1873. //////////
  1874. //
  1875. // DoBeep
  1876. // Beep.
  1877. //
  1878. //////////
  1879.  
  1880. void DoBeep (void)
  1881. {
  1882.     SysBeep(30);
  1883. }
  1884.  
  1885.  
  1886. //////////
  1887. //
  1888. // SetMenuState
  1889. // Set the enabled/disabled state of a menu.
  1890. //
  1891. //////////
  1892.  
  1893. void SetMenuState (MenuReference theMenu, UInt16 theMenuItem, short theState)
  1894. {
  1895. #pragma unused(theMenuItem)
  1896.     SetMenuItemState(theMenu, 0, theState);        // menu item == 0 means the entire menu
  1897. }
  1898.  
  1899.  
  1900. //////////
  1901. //
  1902. // SetMenuItemState
  1903. // Set the enabled/disabled state of a menu item.
  1904. //
  1905. //////////
  1906.  
  1907. void SetMenuItemState (MenuReference theMenu, UInt16 theMenuItem, short theState)
  1908. {
  1909.     if (theState == kEnableMenuItem)
  1910.         EnableItem(theMenu, MENU_ITEM(theMenuItem));
  1911.     else
  1912.         DisableItem(theMenu, MENU_ITEM(theMenuItem));
  1913. }
  1914.  
  1915.  
  1916. //////////
  1917. //
  1918. // SetMenuItemLabel
  1919. // Set the label (that is, the text) of a menu item.
  1920. //
  1921. //////////
  1922.  
  1923. void SetMenuItemLabel (MenuReference theMenu, UInt16 theMenuItem, char *theText)
  1924. {
  1925.     Str255        myString;
  1926.     short        mySIndex, myTIndex;
  1927.  
  1928.     // we need to remove the '&' character while converting to a Pascal string    
  1929.     mySIndex = 1;
  1930.     for (myTIndex = 0; myTIndex < strlen(theText); myTIndex++) {
  1931.         if (theText[myTIndex] != '&') {
  1932.             myString[mySIndex] = theText[myTIndex];
  1933.             mySIndex++;
  1934.         }
  1935.     }
  1936.     
  1937.     myString[0] = mySIndex - 1;
  1938.     
  1939.     SetMenuItemText(theMenu, MENU_ITEM(theMenuItem), myString);
  1940. }
  1941.  
  1942.  
  1943. //////////
  1944. //
  1945. // SetMenuItemCheck
  1946. // Set the check mark state state of a menu item.
  1947. //
  1948. //////////
  1949.  
  1950. void SetMenuItemCheck (MenuReference theMenu, UInt16 theMenuItem, Boolean theState)
  1951. {
  1952.     CheckItem(theMenu, MENU_ITEM(theMenuItem), theState);
  1953. }
  1954.  
  1955.  
  1956. //////////
  1957. //
  1958. // GetPortFromWindowReference 
  1959. // Return the graphics port associated with a window reference.
  1960. //
  1961. //////////
  1962.  
  1963. GrafPtr GetPortFromWindowReference (WindowReference theWindow)
  1964. {
  1965.     return((GrafPtr)theWindow);
  1966. }
  1967.  
  1968.  
  1969. //////////
  1970. //
  1971. // GetWindowReferenceFromPort
  1972. // Return the window reference associated with a graphics port.
  1973. //
  1974. //////////
  1975.  
  1976. WindowReference GetWindowReferenceFromPort (GrafPtr thePort)
  1977. {
  1978.     return((WindowReference)thePort);
  1979. }
  1980.  
  1981.  
  1982. //////////
  1983. //
  1984. // GetWindowWidth
  1985. // Return the width of the specified window.
  1986. //
  1987. //////////
  1988.  
  1989. short GetWindowWidth (WindowReference theWindow)
  1990. {
  1991.     short        myWidth = 0;
  1992.     
  1993.     if (theWindow != NULL)
  1994.         myWidth = (theWindow)->portRect.right - (theWindow)->portRect.left;
  1995.  
  1996.     return(myWidth);
  1997. }
  1998.  
  1999.  
  2000. //////////
  2001. //
  2002. // GetFrontAppWindow
  2003. // Return a reference to the frontmost window (whether or not it's a movie window).
  2004. //
  2005. //////////
  2006.  
  2007. WindowReference GetFrontAppWindow (void)
  2008. {
  2009.     return(FrontWindow());
  2010. }
  2011.  
  2012.  
  2013. //////////
  2014. //
  2015. // GetNextAppWindow
  2016. // Return a reference to the next window (whether or not it's a movie window).
  2017. //
  2018. //////////
  2019.  
  2020. WindowReference GetNextAppWindow (WindowReference theWindow)
  2021. {
  2022.     if (theWindow != NULL)
  2023.         return((WindowPtr)(((WindowRecord*)theWindow)->nextWindow));
  2024.     else
  2025.         return(NULL);
  2026. }
  2027.